﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SecondClient {
    public partial class FrmClient : Form {
        public static Socket ClientSocket;//声明负责通信的socket
        public static int SFlag = 0;//连接服务器成功标志
        Thread th1;//声明一个线程
        public FrmClient() {
            InitializeComponent();
        }

        private void FrmClient_Load(object sender, EventArgs e) {
            //执行新线程时跨线程资源访问检查会提示报错，所以这里关闭检测
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnConnect_Click(object sender, EventArgs e) {
            //1.声明负责通信的套接字
            ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            
            /*IPAddress IP = IPAddress.Parse(txtAddr.Text);//获取设置的IP地址
            int Port = int.Parse(txtPort.Text);//获取设置的端口号
            IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);//指定的端口号和服务器的ip建立一个IPEndPoint对象*/
            if(txtAddr.Text == "" && txtPort.Text == "") {
                MessageBox.Show("请输入需要连接的服务端的IP和端口号", "提示", MessageBoxButtons.OK);
                return;
            } else {
                rchReceive.Text += "正在连接...\n";
                IPAddress IP = IPAddress.Parse(txtAddr.Text);//获取设置的IP地址
                int Port = int.Parse(txtPort.Text);//获取设置的端口号
                IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);
                try {
                    //2.用socket对象的Connect()方法以上面建立的IPEndPoint对象做为参数，向服务器发送连接请求
                    ClientSocket.Connect(iPEndPoint);
                    SFlag = 1;//若连接成功则将标志设置为1

                    rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + txtAddr.Text + "连接成功" + "\n";
                    //rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + ClientSocket.LocalEndPoint.ToString() + "连接成功" + "\n";
                    btnConnect.Enabled = false;//禁止操作连接按钮、

                    //开启一个线程接收数据
                    th1 = new Thread(Receive);
                    th1.IsBackground = true;
                    th1.Start(ClientSocket);
                } catch {
                    MessageBox.Show("服务器未打开");
                }
            }     
        }

        void Receive(Object sk) {
            Socket socketRec = sk as Socket;
            while (true) {
                //3.接收数据
                byte[] receive = new byte[1024];
                ClientSocket.Receive(receive);//调用Receive()接收字节数据
                //打印接收数据
                if (receive.Length > 0) {
                    //rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "接收：";//打印接收时间
                    rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ") + "Server：";//打印接收时间
                    //rchReceive.Text += Encoding.ASCII.GetString(receive);//将字节数据根据ASCII码转成字符串
                    rchReceive.Text += Encoding.UTF8.GetString(receive);//将字节数据根据ASCII码转成字符串
                    //将字节数据根据ASCII码转成字符串
                    rchReceive.Text += "\r\n";
                }
            }
        }

        private void btnSend_Click(object sender, EventArgs e) {
            //只有连接成功了才能发送数据，接收部分因为是连接成功才开启线程，所以不需要使用标志
            if (SFlag == 1) {
                byte[] send = new byte[1024];
                //send = Encoding.ASCII.GetBytes(rchSend.Text);//将文本内容转换成字节发送
                send = Encoding.UTF8.GetBytes(rchSend.Text);//将文本内容转换成字节发送
                //4.调用Send()函数发送数据
                ClientSocket.Send(send);

                //string strlocPort = ClientSocket.LocalEndPoint.ToString();
                string strport = ClientSocket.LocalEndPoint.ToString().Split(':')[1];
                //rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "发送：";
                rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ")  + strport +"发送：";
                rchReceive.Text += rchSend.Text + "\n";//打印发送的数据
                rchSend.Clear();//清除发送框
            }
        }

        private void btnCancelSend_Click(object sender, EventArgs e) {
            rchSend.Clear();//清除发送框
        }

        private void btnClose_Click(object sender, EventArgs e) {
            //保证是在连接状态下退出
            if (SFlag == 1) {
                byte[] send = new byte[1024];
                //关闭客户端时给服务器发送一个退出标志
                //send = Encoding.ASCII.GetBytes("*close*");//关闭客户端时给服务器发送一个退出标志
                send = Encoding.UTF8.GetBytes("*close*");//关闭客户端时给服务器发送一个退出标志
                ClientSocket.Send(send);

                th1.Abort();//关闭线程
                //5.关闭套接字
                ClientSocket.Close();
                btnConnect.Enabled = true;//允许操作按钮
                SFlag = 0;//客户端退出后将连接成功标志程序设置为0
                rchReceive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ");
                rchReceive.Text += "客户端已关闭" + "\n";
                MessageBox.Show("已关闭连接");
            }
        }

        private void rchSend_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.Enter) {
                e.SuppressKeyPress = true;
                this.btnSend_Click(sender, e);//触发button事件
            }
        }
    }
}
